﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using LED_Editor.Model;
using System.IO.Ports;
using LED_Editor.ControllerProgramming;
using LED_Editor.Test;

namespace LED_Editor
{
    public partial class TestControllerProgramming : Form
    {
        public TestControllerProgramming()
        {
            InitializeComponent();
        }

        Controller _controller;

        private void TestControllerProgramming_Load(object sender, EventArgs e)
        {
            _controller = new Controller(serialPort1 );
            _controller.Address = 1;


            IList<FrameStruct> frames = GetFrames(100, new Color[] {
                Color.Red,
                Color.Orange,
                Color.Yellow,
                Color.Green,
                Color.LightBlue ,
                Color.DarkBlue ,
                Color.Violet,
                Color.Red
            });
            foreach (var item in frames)
            {
                _controller.Frames.Add(item);
 
            }
            //_controller.Frames.Add(FrameStruct.Empty);

        }

        private IList<FrameStruct> GetFrames(byte duration, params Color[] colors)
        {
            List<FrameStruct> frames = new List<FrameStruct>();
            for (int i = 0; i < colors.Length - 1; i++)
            {
                FrameStruct frame = new FrameStruct();
                frame.StartR = colors[i].R ;
                frame.StartG = colors[i].G;
                frame.StartB = colors[i].B ;

                frame.EndR = colors[i + 1].R;
                frame.EndG = colors[i + 1].G;
                frame.EndB = colors[i + 1].B;



                frame.Duration = duration;
                frames.Add(frame);
            }
            return frames;
        }

        void _controller_Logging(object sender, LogEventArgs e)
        {
            textBox1.AppendText(e.Message + Environment.NewLine);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //if (backgroundWorker1.IsBusy)
            //    return;


            //Exception error = null;
            //if (!_controller.TryOpenConnection(out error))
            //{
            //    MessageBox.Show(error.Message, "Ошибка открытия порта");
            //    return;
            //}

            //textBox1.AppendText(string.Format("---------------------------------- {0} ---------------------------------" + Environment.NewLine, DateTime.Now.ToLongTimeString()));

            //IEnumerable<Controller> controllers = new List<Controller>() { _controller };

            //backgroundWorker1.RunWorkerAsync(controllers);
            StartAction(LedAction.Programme);
        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            Controller controller = e.Argument as Controller;
            if (controller == null)
            {
                e.Cancel = true;
            }
            Query query = null;
            FormChooseNumber frm = new FormChooseNumber();
            byte number = 0;

            switch (_action)
            {
                case LedAction.Programme:
                    try
                    {
                        controller.Logging += item_Logging;
                        controller.Programme();
                    }
                    finally
                    {
                        controller.Logging -= item_Logging;
                    }
                    break;
                case LedAction.SetColor:
                    if (colorDialog1.ShowDialog() != DialogResult.OK)
                        return;

                    Color color = colorDialog1.Color;

                    byte[] rgb = new  byte[]{color.R,color.G,color.B} ;
                    query = Query.CreateInstance(QueryCodes.SET_COLOR, 1, rgb);

                    break;
                case LedAction.Play :
                    if (frm.ShowDialog() != DialogResult.OK)
                        return;

                    number = (byte)frm.Number;

                    query = Query.CreateInstance(QueryCodes.RUN_PROGRAM, (byte)1, (byte)number);
                    break;
                case LedAction.Pause :
                    query = Query.CreateInstance(QueryCodes.PAUSE_PROGRAM, 1);
                    break;
                case LedAction.Resume:
                    query = Query.CreateInstance(QueryCodes.RESUME_PROGRAM, 1);
                    break;
                case LedAction.IncreaseBrightness:
                    query = Query.CreateInstance(QueryCodes.CHANGE_BRIGHTNESS, (byte)1, (byte)1);
                    break;
                case LedAction.DecreaseBrightness:
                    query = Query.CreateInstance(QueryCodes.CHANGE_BRIGHTNESS, (byte)1, (byte)255);
                    break;
                case LedAction.IncreaseSpeed:
                    query = Query.CreateInstance(QueryCodes.CHANGE_SPEED, (byte)1, (byte)1);
                    break;
                case LedAction.DecreaseSpeed:
                    query = Query.CreateInstance(QueryCodes.CHANGE_SPEED, (byte)1, (byte)255);
                    break;
                case LedAction.StartSync:
                    if (frm.ShowDialog() != DialogResult.OK)
                        return;

                    number = (byte)frm.Number;

                    query = Query.CreateInstance(QueryCodes.START_SYNC, (byte)0, (byte)number);
                    break;
                case LedAction.StopSync:
                    query = Query.CreateInstance(QueryCodes.STOP_SYNC, (byte)0);
                    break;
                default:
                    break;
            }


            if (query == null)
                return;

            try
            {
                controller.Logging += item_Logging;
                _controller.SendQuery(query);
            }
            finally
            {
                controller.Logging -= item_Logging;
            }
        }

        void item_Logging(object sender, LogEventArgs e)
        {
            backgroundWorker1.ReportProgress(0, e.Message);
        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            textBox1.AppendText(e.UserState.ToString() + Environment.NewLine);
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Error ==null)
                MessageBox.Show("Обмен данными завершен", Text,MessageBoxButtons.OK,MessageBoxIcon.Asterisk  );
            else
                MessageBox.Show("Обмен данными завершен c ошибкой:\r\n\r\n" + e.Error.Message, Text, MessageBoxButtons.OK, MessageBoxIcon.Error);

        }

        private void button2_Click(object sender, EventArgs e)
        {
            ControllerProgrammPreviewForm form = new ControllerProgrammPreviewForm();
            form.Controller = _controller;
            form.ShowDialog();  
        }

        void StartAction(LedAction action)
        {
            if (backgroundWorker1.IsBusy)
                return;


            _action = action;

            Exception error = null;
            if (!_controller.TryOpenConnection(out error))
            {
                MessageBox.Show(error.Message, "Ошибка открытия порта");
                return;
            }

            textBox1.AppendText(string.Format("---------------------------------- {0} ---------------------------------" + Environment.NewLine, DateTime.Now.ToLongTimeString()));


            backgroundWorker1.RunWorkerAsync(_controller);
        }

        private void btnSetColor_Click(object sender, EventArgs e)
        {
            StartAction(LedAction.SetColor);
        }

        private static LedAction _action = LedAction.Programme;

        public enum LedAction
        {
            Programme,
            SetColor,
            Play,
            Pause,
            Resume,
            IncreaseBrightness,
            DecreaseBrightness,
            IncreaseSpeed,
            DecreaseSpeed,
            StartSync,
            StopSync

        }

        private void btnPlay_Click(object sender, EventArgs e)
        {
            StartAction(LedAction.Play);
        }

        private void btnPause_Click(object sender, EventArgs e)
        {
            StartAction(LedAction.Pause);
        }

        private void btnResume_Click(object sender, EventArgs e)
        {
            StartAction(LedAction.Resume);
        }

        private void btnIncBrightness_Click(object sender, EventArgs e)
        {
            StartAction(LedAction.IncreaseBrightness);
        }

        private void btnDecBrightness_Click(object sender, EventArgs e)
        {
            StartAction(LedAction.DecreaseBrightness);
        }

        private void btnIncSpeed_Click(object sender, EventArgs e)
        {
            StartAction(LedAction.IncreaseSpeed);
        }

        private void btnDecSpeed_Click(object sender, EventArgs e)
        {
            StartAction(LedAction.DecreaseSpeed);
        }

        private void btnStartSync_Click(object sender, EventArgs e)
        {
            StartAction(LedAction.StartSync);
        }

        private void btnStopSync_Click(object sender, EventArgs e)
        {
            StartAction(LedAction.StopSync);
        }
    }
}
